<HTML>
<HEAD>
  <!-- Created with AOLpress/2.0 -->
  <!-- AP: Created on: 11-Feb-2001 -->
  <!-- AP: Last modified: 29-Jun-2005 -->
  <TITLE>The basic spline data structures of FontForge</TITLE>
  <LINK REL="icon" href="fftype16.png">
  <LINK REL="stylesheet" TYPE="text/css" HREF="FontForge.css">
</HEAD>
<BODY>
<DIV id="in">
<H2>
  Data Types
</H2>
<P>
This describes two different types of fonts, a SplineFont (which is a postscript
or truetype font) and a BDFFont (bitmap font, essentially a bdf file). There
are some similarities between the two data structures, each is basically
an array (possibly with holes in it) of characters. Each font also contains
information like the fontname.
<P>
The <A HREF="#SplineFont">SplineFont</A> consists of a bunch of
<A HREF="#SplineChar">SplineChars</A>, each containing four layers,
<UL>
  <LI>
    A foreground layer which contains all the interesting stuff that gets put
    into the final font
    <UL>
      <LI>
	a series of paths (called <A HREF="#SplinePointList">SplineSet</A>s or
	<A HREF="#SplinePointList">SplinePointList</A> sorry, I gave the data structure
	two different names)
      <LI>
	a series of references to other characters (called
	<A HREF="#RefChar">RefChar</A>s)
      <LI>
	a width
      <LI>
	<A HREF="#Undoes">undoes</A>
    </UL>
  <LI>
    A background layer (which is used to allow people to trace images of characters)
    and can contain
    <UL>
      <LI>
	a series of <A HREF="#SplinePointList">SplineSet</A>s
      <LI>
	A series of <A HREF="#ImageList">images</A>
      <LI>
	<A HREF="#Undoes">undoes</A>
    </UL>
  <LI>
    A grid layer, which is shared by all the characters in a font and in which
    you can put lines to indicate the Cap Height, X Height, etc. Actually you
    can put anything there but those are the obviously useful things. It will
    be seen in all characters. It contains
    <UL>
      <LI>
	A series of <A HREF="#SplinePointList">SplineSet</A>s
      <LI>
	<A HREF="#Undoes">undoes</A>
    </UL>
  <LI>
    A hint layer, whose format is completely different from anything else and
    consists of horizontal and vertical hints, which in turn are just a starting
    location and a width (indicating the stem. The width can be negative.)
    <UL>
      <LI>
	A set of <A HREF="#Hints">hints</A>. Hints need the special tools from the
	hint menu for editing them.
      <LI>
	<STRONG>!!!! I do not have a way of undoing hint operations !!!!</STRONG>
    </UL>
</UL>
<P>
In multilayered mode there can be many foreground layers which can be stroked
or filled. Bitmap images may also be included.
<P>
Every SplineChar has a name associated with it, a unicode encoding and a
its original position in the font.
<P>
A SplineSet consists of a start point and an end point, and whatever splines
connect them. The start point and the end point may be the same, this either
indicates a closed path, or a degenerate path with only one point on it.
<P>
A SplinePoint contains an x,y location of the point, and the locations of
the two control points associated with that point. A control point may be
coincident with the main point. SplinePoints may connect to two splines,
a previous Spline and a next Spline. A Spline contains pointers to two
SplinePoints (a start and an end point) it also contains the parameters of
the B&eacute;zier curve that those two points describe (x = a*t^3+b*t^2+c*t+d,
y=ditto). Splines are straight lines if the two control points that are
meaningful to that spline are coincident with their respective SplinePoints.
A spline contains a bit indicating whether it is order2 (truetype quadratic
format) or order3 (postscript cubic format). If it is quadratic there is
really only one control point, ff uses the convention that the control points
on the start and end SplinePoints have the same location.
<P>
A font's encoding is stored in a separate data structure called an EncMap.
This structure controls what glyph goes where and also contains a pointer
to an Encoding structure which provides a name for the encoding. The EncMap
contains two arrays, the <CODE>map</CODE> and the <CODE>backmap</CODE>. The
map is indexed by the character's encoding and provides the position (in
the associated splinefont's glyph list) of the associated glyph. The backmap
provides the reverse mapping, it is indexed by a glyph's position in the
splinefont and provides an encoding for that glyph. (Note: the map array
may map several encodings to one glyph, the backmap will only indicate one
of those.)
<P>
A <A HREF="#BDFFont">BDFFont</A> is always associated with a (possibly empty)
SplineFont and its EncMap, it consists of an array of
<A HREF="#BDFChar">BDFChars</A>, each containing
<UL>
  <LI>
    a bitmap
  <LI>
    possibly a floating selection
  <LI>
    a name
  <LI>
    <A HREF="#Undoes">undoes</A>
  <LI>
    A pointer to the <A HREF="#SplineChar">SplineChar</A> with which it is associated
</UL>
<P>
The array is ordered the same way the SplineFont's array is ordered, and
the same EncMap can be used for both.
<BLOCKQUOTE>
  <PRE>/* Copyright (C) 2000-2003 by George Williams */
/*
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.

 * The name of the author may not be used to endorse or promote products
 * derived from this software without specific prior written permission.

 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef _SPLINEFONT_H
#define _SPLINEFONT_H

#include "basics.h"
#include "charset.h"

enum <A NAME="linejoin">linejoin</A> {
    lj_miter,		/* Extend lines until they meet */
    lj_round,		/* circle centered at the join of expand radius */
    lj_bevel		/* Straight line between the ends of next and prev */
};
enum <A NAME="linecap">linecap</A> {
    lc_butt,		/* equiv to lj_bevel, straight line extends from one side to other */
    lc_round,		/* semi-circle */
    lc_square		/* Extend lines by radius, then join them */
};

typedef struct strokeinfo {
    double radius;
    enum linejoin join;
    enum linecap cap;
    unsigned int calligraphic: 1;
    double penangle;
    double thickness;			/* doesn't work */
} <A NAME="StrokeInfo">StrokeInfo</A>;
</PRE>
</BLOCKQUOTE>
<P>
The above data structure is used by the ExpandStroke routines which will
turn a path into a filled shape. The information above provides the various
controls for those routines. They mean essentially what you expect them to
me in postscript.
<BLOCKQUOTE>
  <PRE>typedef struct ipoint {
    int x;
    int y;
} <A NAME="IPoint">IPoint</A>;
</PRE>
</BLOCKQUOTE>
<P>
An integer point.
<BLOCKQUOTE>
  <PRE>typedef struct basepoint {
    double x;
    double y;
} <A NAME="BasePoint">BasePoint</A>;
</PRE>
</BLOCKQUOTE>
<P>
A double point. This provides the location of
<A HREF="#SplinePoint">SplinePoints</A> and their control points.
<BLOCKQUOTE>
  <PRE>typedef struct tpoint {
    double x;
    double y;
    double t;
} <A NAME="TPoint">TPoint</A>;
</PRE>
</BLOCKQUOTE>
<P>
A double point with a "t" value. Indicates where that location occurs on
a spline. (the start point itself is a t=0, the end point at t=1, intermediate
points have intermediate values). Used when trying to approximate new splines.
<BLOCKQUOTE>
  <PRE>typedef struct dbounds {
    double minx, maxx;
    double miny, maxy;
} DBounds;
</PRE>
</BLOCKQUOTE>
<P>
The bounding box of a <A HREF="#Spline">Spline</A>,
<A HREF="#SplineChar">SplineChar</A>, <A HREF="#RefChar">RefChar</A>,
<A HREF="#ImageList">Image</A>, or whatever else needs a bounding box.
<BLOCKQUOTE>
  <PRE>typedef struct bdffloat {
    int16 xmin,xmax,ymin,ymax;
    int16 bytes_per_line;
    uint8 *bitmap;
} <A NAME="BDFFloat">BDFFloat</A>;
</PRE>
</BLOCKQUOTE>
<P>
The floating selection in a <A HREF="#BDFChar">BDFChar</A>.
<BLOCKQUOTE>
  <PRE>typedef struct undoes {
    struct undoes *next;
    enum undotype { ut_none=0, ut_state, ut_tstate, ut_width,
	    ut_bitmap, ut_bitmapsel, ut_composite, ut_multiple } undotype;
    union {
	struct {
	    int16 width;
	    int16 lbearingchange;
	    <A HREF="#SplinePointList">struct splinepointlist</A> *splines;
	    <A HREF="#RefChar">struct refchar</A> *refs;
	    <A HREF="#ImageList">struct imagelist</A> *images;
	} state;
	int width;
	struct {
	    /*int16 width;*/	/* width should be controlled by postscript */
	    int16 xmin,xmax,ymin,ymax;
	    int16 bytes_per_line;
	    uint8 *bitmap;
	    <A HREF="#BDFFloat">BDFFloat</A> *selection;
	    int pixelsize;
	} bmpstate;
	struct {		/* copy contains an outline state and a set of bitmap states */
	    struct undoes *state;
	    struct undoes *bitmaps;
	} composite;
	struct {
	    struct undoes *mult; /* copy contains several sub copies (composites, or states or widths or...) */
	} multiple;
    uint8 *bitmap;
    } u;
} <A NAME="Undoes">Undoes</A>;
</PRE>
</BLOCKQUOTE>
<P>
The undo data structure. Used by both <A HREF="#SplineChar">SplineChar</A>
and <A HREF="#BDFChar">BDFChar</A>. Also used to contain the local clipboard.
Every character layer has several Undoes (up to about 10 or so, it's
configurable) that allow it to go back several operations, these are linked
together on the next field (redos are handled similarly, of course).
<P>
Undoes come in several types, ut_none is only used by the clipboard when
it is empty.
<P>
ut_state is used by SplineChars and it contains a dump of the current state
of one layer of the character. Obviously things could be optimized a great
deal here, but this is easy. ut_tstate has the same data structure as ut_state,
it is used during transformations and is just a flag that tells the display
to draw the original as well as the currently transformed thing (so you can
see what you've done).
<P>
ut_state is also used by the clipboard when copying a SplineChar or a piece
of a SplineChar.
<P>
ut_width is used by SplineChars when the width (and nothing else) changes.
<P>
ut_bitmap is used by BDFChars and is a dump of the current state of the bitmap.
Again there is room for optimization here, but this is easy.
<P>
ut_bitmapsel is used when doing a copy of a BDFChar. If there is a selection
it (and it alone) gets copied into the selection field of the bmpstate structure.
If there is no selection the entire bitmap is converted into a
<A HREF="#BDFFloat">floating selection</A> and copied into the selection
field.
<P>
ut_composite is used when doing a copy from the
<A HREF="views.html#FontView">FontView</A> where you are copying both the
splines and the bitmaps of a character.
<P>
ut_mult is used when doing a copy from the FontView where you are copying
more than one character.
<BLOCKQUOTE>
  <PRE>typedef struct bdfchar {
    <A HREF="#SplineChar">struct splinechar</A> *sc;
    int16 xmin,xmax,ymin,ymax;
    int16 width;
    int16 bytes_per_line;
    uint8 *bitmap;
    int orig_pos;
    <A HREF="views.html#BitmapView">struct bitmapview</A> *views;
    <A HREF="#Undoes">Undoes</A> *undoes;
    <A HREF="#Undoes">Undoes</A> *redoes;
    unsigned int changed: 1;
    unsigned int byte_data: 1;		/* for anti-aliased chars entries are grey-scale bytes not bw bits */
    <A HREF="#BDFFloat">BDFFloat</A> *selection;
} <A NAME="BDFChar">BDFChar</A>;
</PRE>
</BLOCKQUOTE>
<P>
The basic bitmap character structure. There's a link to the SplineChar used
to create the bitmap. Then the bounding box of the bitmap, the character's
width (in pixels of course), the number of bytes per row of the bitmap array,
a pointer to an array containing the bitmap. The bitmap is stored with 8bits
packed into a byte, the high order bit is left most. Every row begins on
a new byte boundary. There are (xmax-xmin+1) bits in each row and (xmax-xmin+8)/8
bytes in each row. There are (ymax-ymin+1) rows. A bit-value of 1 means there
bit should be drawn, 0 means it is transparent. Then the encoding in the
current font. A linked list of BitmapView structures all of which look at
this bitmap (so any changes to this bitmap need to cause a redraw in all
views). A set of undoes and redoes. A flag indicating whether the thing has
been changed since it was last saved to disk.
<P>
Up to this point I've been talking about bitmaps. It is also possible to
have a bytemap. The data structure is exactly the same, except that each
pixel is represented by a byte rather than a bit. There is a clut for this
in the BDFFont (it's the same for every character), but basically
0=&gt;transparent, (2^n-1) =&gt;fully drawn, other values are shades of grey
between. Can handle depths of 1,2,4 and 8 bits/pixel.
<P>
The last thing in the BDFChar is a (/an optional) floating selection. Only
present if the user has made a selection or done a paste or something like
that.
<BLOCKQUOTE>
  <PRE>typedef struct bdffont {
    <A HREF="#SplineFont">struct splinefont</A> *sf;
    int glyphcnt;
    <A HREF="#BDFChar">BDFChar</A> **glyphs;		/* an array of charcnt entries */
    int pixelsize;
    int ascent, descent;
    struct bdffont *next;
    struct clut *clut;		/* Only for anti-aliased fonts */
} <A NAME="BDFFont">BDFFont</A>;
</PRE>
</BLOCKQUOTE>
<P>
The basic bitmap font. Contains a reference to the
<A HREF="#SplineFont">SplineFont</A> to which it is attached. Then a size
and an array of BDFChars (note there may be NULL entries in the array if
no character is defined for that encoding). Then a temporary array which
is used in one set of routines while reencoding the font. The pixelsize of
the em-square. The ascent and descent (in pixels), these should sum to the
em-square. A character set which will match that in the SplineFont. A pointer
to the next bitmap font associated with this SplineFont.
<P>
If we are dealing with a byte font, then there will also be a clut. This
contains a count of the number of entries in the array, and then the array
itself. Currently the number of entries here is always 16, but that could
change.
<BLOCKQUOTE>
  <PRE>enum pointtype { pt_curve, pt_corner, pt_tangent };
typedef struct splinepoint {
    <A HREF="#BasePoint">BasePoint</A> me;
    <A HREF="#BasePoint">BasePoint</A> nextcp;		/* control point */
    <A HREF="#BasePoint">BasePoint</A> prevcp;		/* control point */
    unsigned int nonextcp:1;
    unsigned int noprevcp:1;
    unsigned int nextcpdef:1;
    unsigned int prevcpdef:1;
    unsigned int selected:1;	/* for UI */
    unsigned int pointtype:2;
    unsigned int isintersection: 1;
    uint16 flex;		/* This is a flex serif have to go through icky flex output */
    <A HREF="#Spline">struct spline</A> *next;
    <A HREF="#Spline">struct spline</A> *prev;
} <A NAME="SplinePoint">SplinePoint</A>;
</PRE>
</BLOCKQUOTE>
<P>
A SplinePoint is located at the position specified by "me". The control point
associated with the next <A HREF="#Spline">Spline</A> is positioned at nextcp,
while that associated with the previous Spline is at prevcp. Then there are
a couple of flags that simplify tests. If the nextcp is degenerate (ie. at
the same place as me) then nonextcp is set, similarly for prevcp. If the
user has not touched the control points then they will have their default
values, and when the user moves the point around fontforge will update the
control points appropriately, if they do not have default values then fontforge
will only offset them.
<P>
If the point is selected then that bit will be set.
<P>
Every point is classified as a curve point, a corner point and a tangent
point.
<P>
The isintersection bit is used internally to the SplineOverlap routines.
The flex value is for flex hints. It is read in from a type1 font and then
ignored. Someday I may use it.
<P>
Finally we have pointers to the two Splines than connect to this point.
<BLOCKQUOTE>
  <PRE>typedef struct linelist {
    IPoint here;
    struct linelist *next;
} <A NAME="LineList">LineList</A>;

typedef struct linearapprox {
    double scale;
    unsigned int oneline: 1;
    unsigned int onepoint: 1;
    struct linelist *lines;
    struct linearapprox *next;
} <A NAME="LinearApprox">LinearApprox</A>;
</PRE>
</BLOCKQUOTE>
<P>
These are the lines used to approximate a <A HREF="#Spline">Spline</A> when
drawing it. They are cached so they don't need to be regenerated each time.
There's a different set of lines for every scale (as there is a different
amount of visible detail). They get freed and regenerated if the Spline changes.
<BLOCKQUOTE>
  <PRE>typedef struct spline1d {
    double a, b, c, d;
} <A NAME="Spline1D">Spline1D</A>;

typedef struct spline {
    unsigned int islinear: 1;
    unsigned int isticked: 1;
    unsigned int isneeded: 1;
    unsigned int isunneeded: 1;
    unsigned int ishorvert: 1;
    unsigned int order2: 1;
    <A HREF="#SplinePoint">SplinePoint</A> *from, *to;
    <A HREF="#Spline1D">Spline1D</A> splines[2];		/* splines[0] is the x spline, splines[1] is y */
    <A HREF="#LinearApprox">struct linearapprox</A> *approx;
    /* Possible optimizations:
	Precalculate bounding box
	Precalculate points of inflection
    */
} <A NAME="Spline">Spline</A>;
</PRE>
</BLOCKQUOTE>
<P>
A spline runs from the <CODE>from</CODE>
<A HREF="#SplinePoint">SplinePoint</A> to the <CODE>to</CODE> SplinePoint.
If both control points of a Spline are degenerate, then the Spline is linear
(actually there are some other case that will lead to linear splines, sometimes
these will be detected and turned into the canonical case, other times they
will not be). The remaining bits are used when processing Splines in various
functions. Most are used in the SplineOverlap routines, but some are used
in other places too.
<P>
The Spline1D structures give the equations for the x and y coordinates
respectively (splines[0] is for x, splines[1] is for y).
<BLOCKQUOTE>
  <PRE>typedef struct splinepointlist {
    <A HREF="#SplinePoint">SplinePoint</A> *first, *last;
    struct splinepointlist *next;
} <A NAME="SplinePointList">SplinePointList</A>, <A NAME="SplineSet">SplineSet</A>;
</PRE>
</BLOCKQUOTE>
<P>
A SplinePointList (or a SplineSet) is a collection of
<A HREF="#Spline">Spline</A>s and <A HREF="#SplinePoint">SplinePoint</A>s.
Every SplinePoint can connect to two Splines (next and prev). Every Spline
connects to two SplinePoints (from and to). A SplinePointList is a connected
path. There are three cases:
<UL>
  <LI>
    <CODE>first != last</CODE> which means that we have an open path. Here
    first-&gt;prev==NULL and last-&gt;next==NULL.
  <LI>
    <CODE>first == last</CODE> and <CODE>first-&gt;prev==NULL</CODE> which means
    we have a degenerate path consisting of a single point, and
    last-&gt;next==NULL as well
  <LI>
    <CODE>first == last</CODE> and <CODE>first-&gt;prev!=NULL</CODE> which means
    we have a closed path. This should be the most common case.
</UL>
<P>
Generally a series of paths will make up a character, and they are linked
together on the next field.
<BLOCKQUOTE>
  <PRE>typedef struct refchar {
    int16 adobe_enc, orig_pos
    int unicode_enc;		/* used by paste */
    double transform[6];	/* transformation matrix (first 2 rows of a 3x3 matrix, missing row is 0,0,1) */
    <A HREF="#SplinePointList">SplinePointList</A> *splines;
    struct refchar *next;
    unsigned int checked: 1;
    unsigned int selected: 1;
    <A HREF="#DBounds">DBounds</A> bb;
    <A HREF="#SplineChar">struct splinechar</A> *sc;
} <A NAME="RefChar">RefChar</A>;
</PRE>
</BLOCKQUOTE>
<P>
A <A HREF="#SplineChar">SplineChar</A> may contain a reference to another
character. For instance "Agrave" might contain a reference to an "A" and
a "grave". There are three different encoding values, of which orig_pos is
not always up to date. Adobe_enc gives the location in the Adobe Standard
Encoding which is used by the seac command in type1 fonts. If this is -1
then the character isn't in the adobe encoding and it won't be possible to
put a reference to it into a Type1 font (truetype doesn't have this restriction,
it has other ones). The transformation matrix is a standard postscript
transformation matrix (3 rows of 2 columns. First 2 rows provide standard
rotation/scaling/flipping/skewing/... transformations, last row provides
for translations. (Both postscript and truetype have restrictions on what
kinds of transformations are acceptable). The splines field provides a quick
way of drawing the referred character, it is the result of applying the
transformation matrix on all splines in the refered character. There may
be several referred characters and they are linked together on the next field.
The checked field is used to insure that we don't have any loops (ie. on
characters which refer to themselves). The selected field indicates that
the reference is selected. The bb field provides a transformed bounding box.
And the sc field points to the SplineChar we are referring to.
<BLOCKQUOTE>
  <PRE>typedef struct kernpair {
    struct splinechar *sc;
    int off;
    struct kernpair *next;
} <A NAME="KernPair">KernPair</A>;
</PRE>
</BLOCKQUOTE>
<P>
If a character should be kerned with another, then this structure provides
that info. Every SplineChar has a linked list of KernPairs attached to it.
In that list the sc field indicates the other character in the pair, and
off defines the offset between them (or rather the difference from what their
respective left and right bearings would lead you to believe it should be).
Next points to the next kernpair.
<BLOCKQUOTE>
  <PRE>typedef struct hints {
    double base, width;
    double b1, b2, e1, e2;
    double ab, ae;
    unsigned int adjustb: 1;
    unsigned int adjuste: 1;
    struct hints *next;
} <A NAME="Hints">Hints</A>;
</PRE>
</BLOCKQUOTE>
<P>
The only important fields here are base, width and next. The others are used
temporarily by the SplineFill routines. Base gives the location (in either
x or y space) of where the stem starts, and width is how long it is. Width
may be negative (in which case base is where the stem ends). Next points
to the next hint for the character.
<BLOCKQUOTE>
  <PRE>typedef struct imagelist {
    struct gimage *image;
    double xoff, yoff;		/* position in character space of upper left corner of image */
    double xscale, yscale;	/* scale to convert one pixel of image to one unit of character space */
    <A HREF="#DBounds">DBounds</A> bb;
    struct imagelist *next;
    unsigned int selected: 1;
} <A NAME="ImageList">ImageList</A>;
</PRE>
</BLOCKQUOTE>
<P>
SplineChars may have images in their backgrounds (or foregrounds for multilayer
characters). This structure contains a pointer to the image to be displayed,
an indication of where it should be positioned, and how it should be scaled
(I do not support any other transformations on images). The bounding box
is after the transformations have been applied. The next field points to
the next image, and selected indicates whether this one is selected or not.
<BLOCKQUOTE>
  <PRE>typedef struct splinechar {
    char *name;
    int enc, unicodeenc;
    int width;
    int16 lsidebearing;		/* only used when reading in a type1 font */
    int16 ttf_glyph;		/* only used when writing out a ttf font */
    <A HREF="#SplinePointList">SplinePointList</A> *splines;
    <A HREF="#Hints">Hints</A> *hstem;		/* hstem hints have a vertical offset but run horizontally */
    <A HREF="#Hints">Hints</A> *vstem;		/* vstem hints have a horizontal offset but run vertically */
    <A HREF="#RefChar">RefChar</A> *refs;
    <A HREF="views.html#CharView">struct charview</A> *views;	/* All CharViews that look at us */
    <A HREF="#SplineFont">struct splinefont</A> *parent;
    unsigned int changed: 1;
    unsigned int changedsincelasthhinted: 1;
    unsigned int changedsincelastvhinted: 1;
    unsigned int manualhints: 1;
    unsigned int ticked: 1;	/* For reference character processing */
    unsigned int changed_since_autosave: 1;
    unsigned int widthset: 1;	/* needed so an emspace char doesn't disappear */
    struct splinecharlist { struct splinechar *sc; struct splinecharlist *next;} *dependents;
	    /* The dependents list is a list of all characters which reference*/
	    /*  the current character directly */
    <A HREF="#SplinePointList">SplinePointList</A> *backgroundsplines;
    <A HREF="#ImageList">ImageList</A> *backimages;
    <A HREF="#Undoes">Undoes</A> *undoes[2];
    <A HREF="#Undoes">Undoes</A> *redoes[2];
    <A HREF="#KernPair">KernPair</A> *kerns;
    uint8 *origtype1;		/* The original type1 (unencoded) character string */
    int origlen;		/*  its length. These get freed once the user has changed */
				/*  the character. Until then the preserve things like */
				/*  hint substitution which we wouldn't otherwise understand */
} <A NAME="SplineChar">SplineChar</A>;
</PRE>
</BLOCKQUOTE>
<P>
Every character has a name (sometimes it is ".notdef" but it's there). A
location (encoding) in the current font, a unicode code point (which may
be -1 if not in unicode). Every character has a width. The next two fields
are only meaningful when loading or saving a font in the appropriate format.
lbearing is needed to handle seac commands, and the ttf_glyph is needed for
just about everything when writing a ttf font. The splines field gives all
the foreground paths (<A HREF="#SplinePointList">SplinePointLists</A>). Hints
for horizontal and vertical stems. A set of other characters referenced in
this one, again only in the foreground. Then a linked list of all
<A HREF="views.html#CharView">CharViews</A> displaying this SplineChar (if
this guy changes, all must be updated to reflect the change). A pointer to
the <A HREF="#SplineFont">SplineFont</A> that contains us. A set of bits:
changed means the character has changed since the last save to disk,
changedsincelasthhinted means that we need to run autohint on the horizontal
stems, changedsincelastvhinted for vertical stems. Manual hints means the
user has taken control of providing hints, and we should only run autohint
if explicitly asked to. Ticked is a temporary field usually to avoid infinite
loops of refered characters. changed_since_autosave indicates that the next
time we update our autosave database we should write this character to it.
Widthset means the user has changed the width. If we didn't have this bit
we might think that an em space had nothing in it (instead of having an em-space
in it).
<P>
If a SplineChar is refered to in another character, then when we change the
original we must also update anything that refers to it (if we change A,
we must also redisplay Agrave).
<P>
Then backgroundsplines represent the SplinePointLists in the background layer,
and backimages represent the images in the background layers.
<P>
Undoes[0] contains undoes for the foreground and undoes[1] contains undoes
for the background. Same for redoes.
<P>
Finally kerns provides a list of kerning data for any special characters
that follow this one. For instance the combination "VA" might need kerning,
then the SplineChar representing "V" would have a pointer to a
<A HREF="#KernPair">KernPair</A> with data on "A".
<BLOCKQUOTE>
  <PRE>typedef struct splinefont {
    char *fontname, *fullname, *familyname, *weight;
    char *copyright;
    char *filename;
    char *version;
    double italicangle, upos, uwidth;
    int ascent, descent;
    int glyphcnt;
    <A HREF="#SplineChar">SplineChar</A> **glyphs;
    unsigned int changed: 1;
    unsigned int changed_since_autosave: 1;
    unsigned int display_antialias: 1;
    unsigned int dotlesswarn: 1;		/* User warned that font doesn't have a dotless i character */
    /*unsigned int wasbinary: 1;*/
    <A HREF="views.html#FontView">struct fontview</A> *fv;
    enum charset encoding_name;
    <A HREF="#SplinePointList">SplinePointList</A> *gridsplines;
    <A HREF="#Undoes">Undoes</A> *gundoes, *gredoes;
    <A HREF="#BDFFont">BDFFont</A> *bitmaps;
    char *origname;		/* filename of font file (ie. if not an sfd) */
    char *autosavename;
    int display_size;
} <A NAME="SplineFont">SplineFont</A>;
</PRE>
</BLOCKQUOTE>
<P>
The first four names are taken straight out of PostScript, as are copyright,
version, italicangle, underlinepos, underlineweight. Ascent and descent together
sum to make the em-square. Normally this will be 1000, but you can change
that if you want.
<P>
Charcnt says how big the chars array will be. There may be holes (ie. NULL
values) in the array.
<P>
Changed indicates that some character, bitmap, metric, something has changed
since we last saved the file. changed_since_autosave means that something
has changed since autosave last happened (so we should actually process this
font the next time autosave rolls around).
<P>
Display_antialias means we are displaying an antialias bytemap font in the
<A HREF="views.html#FontView">FontView</A>, rather than a bitmap font. These
look better but are slower.
<P>
Dotlesswarn means that we've warned the user when s/he attempted to create
an accented character based on i or j and a dotless version of those characters
was not present in the font (there's no point in warning him again. The operation
proceeded with a dotted version).
<P>
There is only one <A HREF="views.html#FontView">FontView</A> associated with
a font (other data structures allowed for multiple views, but the font does
not).
<P>
The font has a characterset and an encoding.
<P>
Gridsplines contains the <A HREF="#SplinePointList">SplinePointLists</A>
for all the splines displayed as background grids for characters. And gundoes
and gredoes are the un/redoes associated with them.
<P>
Bitmaps contains all the bitmaps that have been generated for this SplineFont.
<P>
Origname contains the name of the file we read in to get this one. Filename
above contains the name of an .sfd file associated with this font, but origname
can also contain random postscript or truetype fonts.
<P>
Autosavename indicates the name currently being used to save crash recovery
stuff to disk.
<P>
Display_size indicates how big we'd like the FontView to display our font.
<H2>
  Function declarations
</H2>
<P>
<BLOCKQUOTE>
  <PRE>struct fontdict;		/* the next four data structures are in psfont.h */
struct chars;
struct findsel;
struct charprocs;
enum charset;			/* in charset.h */

extern SplineFont *SplineFontFromPSFont(struct fontdict *fd);
extern int SFOneWidth(SplineFont *sf);
extern struct chars *SplineFont2Chrs(SplineFont *sf, int round);
enum fontformat { ff_pfa, ff_pfb, ff_ptype3, ff_ptype0, ff_ttf, ff_none };
extern int WritePSFont(char *fontname,SplineFont *sf,enum fontformat format);
extern int WriteTTFFont(char *fontname,SplineFont *sf);
int SFReencodeFont(SplineFont *sf,enum charset new_map);

extern int DoubleNear(double a,double b);
extern int DoubleNearish(double a,double b);

extern void LineListFree(LineList *ll);
extern void LinearApproxFree(LinearApprox *la);
extern void SplineFree(Spline *spline);
extern void SplinePointFree(SplinePoint *sp);
extern void SplinePointListFree(SplinePointList *spl);
extern void SplinePointListsFree(SplinePointList *head);
extern void RefCharFree(RefChar *ref);
extern void RefCharsFree(RefChar *ref);
extern void UndoesFree(Undoes *undo);
extern void HintsFree(Hints *h);
extern Hints *HintsCopy(Hints *h);
extern SplineChar *SplineCharCopy(SplineChar *sc);
extern BDFChar *BDFCharCopy(BDFChar *bc);
extern void ImageListsFree(ImageList *imgs);
extern void SplineCharFree(SplineChar *sc);
extern void SplineFontFree(SplineFont *sf);
extern void SplineRefigure(Spline *spline);
extern Spline *SplineMake(SplinePoint *from, SplinePoint *to);
extern LinearApprox *SplineApproximate(Spline *spline, double scale);
extern int SplinePointListIsClockwise(SplineSet *spl);
extern void SplineSetFindBounds(SplinePointList *spl, DBounds *bounds);
extern void SplineCharFindBounds(SplineChar *sc,DBounds *bounds);
extern void SplineFontFindBounds(SplineFont *sf,DBounds *bounds);
extern void SplinePointCategorize(SplinePoint *sp);
extern void SCCategorizePoints(SplineChar *sc);
extern SplinePointList *SplinePointListCopy(SplinePointList *base);
extern SplinePointList *SplinePointListCopySelected(SplinePointList *base);
extern SplinePointList *SplinePointListTransform(SplinePointList *base, double transform[6], int allpoints );
extern SplinePointList *SplinePointListShift(SplinePointList *base, double xoff, int allpoints );
extern SplinePointList *SplinePointListRemoveSelected(SplinePointList *base);
extern void SplinePointListSet(SplinePointList *tobase, SplinePointList *frombase);
extern void SplinePointListSelect(SplinePointList *spl,int sel);
extern void SCRefToSplines(SplineChar *sc,RefChar *rf);
extern void SCReinstanciateRefChar(SplineChar *sc,RefChar *rf);
extern void SCReinstanciateRef(SplineChar *sc,SplineChar *rsc);
extern void SCRemoveDependent(SplineChar *dependent,RefChar *rf);
extern void SCRemoveDependents(SplineChar *dependent);
extern RefChar *SCCanonicalRefs(SplineChar *sc, int isps);
extern void BCCompressBitmap(BDFChar *bdfc);
extern void BCRegularizeBitmap(BDFChar *bdfc);
extern void BCPasteInto(BDFChar *bc,BDFChar *rbc,int ixoff,int iyoff, int invert);
extern BDFChar *SplineCharRasterize(SplineChar *sc, int pixelsize);
extern BDFFont *SplineFontRasterize(SplineFont *sf, int pixelsize);
extern BDFChar *SplineCharAntiAlias(SplineChar *sc, int pixelsize,int linear_scale);
extern BDFFont *SplineFontAntiAlias(SplineFont *sf, int pixelsize,int linear_scale);
extern void BDFCharFree(BDFChar *bdfc);
extern void BDFFontFree(BDFFont *bdf);
extern void BDFFontDump(char *filename,BDFFont *font, char *encodingname);
extern double SplineSolve(Spline1D *sp, double tmin, double tmax, double sought_y, double err);
extern void SplineFindInflections(Spline1D *sp, double *_t1, double *_t2 );
extern int NearSpline(struct findsel *fs, Spline *spline);
extern double SplineNearPoint(Spline *spline, BasePoint *bp, double fudge);
extern void SCMakeDependent(SplineChar *dependent,SplineChar *base);
extern SplinePoint *SplineBisect(Spline *spline, double t);
extern Spline *ApproximateSplineFromPoints(SplinePoint *from, SplinePoint *to,
	TPoint *mid, int cnt);
extern int SplineIsLinear(Spline *spline);
extern int SplineInSplineSet(Spline *spline, SplineSet *spl);
extern void SplineCharMerge(SplineSet **head);
extern void SplineCharSimplify(SplineSet *head);
extern void SplineCharRemoveTiny(SplineSet *head);
extern SplineFont *SplineFontNew(void);
extern SplineFont *SplineFontBlank(int enc,int charcnt);
extern SplineSet *SplineSetReverse(SplineSet *spl);
extern SplineSet *SplineSetsExtractOpen(SplineSet **tbase);
extern SplineSet *SplineSetsCorrect(SplineSet *base);
extern void SPAverageCps(SplinePoint *sp);
extern void SplineCharDefaultPrevCP(SplinePoint *base, SplinePoint *prev);
extern void SplineCharDefaultNextCP(SplinePoint *base, SplinePoint *next);
extern void SplineCharTangentNextCP(SplinePoint *sp);
extern void SplineCharTangentPrevCP(SplinePoint *sp);
extern int PointListIsSelected(SplinePointList *spl);
extern void SplineSetsUntick(SplineSet *spl);
extern void SFOrderBitmapList(SplineFont *sf);

extern SplineSet *SplineSetStroke(SplineSet *spl,StrokeInfo *si);
extern SplineSet *SplineSetRemoveOverlap(SplineSet *base);

extern void FindBlues( SplineFont *sf, double blues[14], double otherblues[10]);
extern void FindHStems( SplineFont *sf, double snaps[12], double cnt[12]);
extern void FindVStems( SplineFont *sf, double snaps[12], double cnt[12]);
extern void SplineCharAutoHint( SplineChar *sc);
extern void SplineFontAutoHint( SplineFont *sf);
extern int AfmSplineFont(FILE *afm, SplineFont *sf,int type0);
extern char *EncodingName(int map);

extern int SFDWrite(char *filename,SplineFont *sf);
extern int SFDWriteBak(SplineFont *sf);
extern SplineFont *SFDRead(char *filename);
extern SplineFont *SFReadTTF(char *filename);
extern SplineFont *LoadSplineFont(char *filename);
extern SplineFont *ReadSplineFont(char *filename);	/* Don't use this, use LoadSF instead */

extern SplineChar *SCBuildDummy(SplineChar *dummy,SplineFont *sf,int i);
extern SplineChar *SFMakeChar(SplineFont *sf,int i);
extern BDFChar *BDFMakeChar(BDFFont *bdf,int i);

extern void SCUndoSetLBearingChange(SplineChar *sc,int lb);
extern Undoes *SCPreserveState(SplineChar *sc);
extern Undoes *SCPreserveWidth(SplineChar *sc);
extern Undoes *BCPreserveState(BDFChar *bc);
extern void BCDoRedo(BDFChar *bc,struct fontview *fv);
extern void BCDoUndo(BDFChar *bc,struct fontview *fv);

extern int SFIsCompositBuildable(SplineFont *sf,int unicodeenc);
extern void SCBuildComposit(SplineFont *sf, SplineChar *sc, int copybmp,
	struct fontview *fv);

extern void BDFFontDump(char *filename,BDFFont *font, char *encodingname);
extern int getAdobeEnc(char *name);

extern SplinePointList *SplinePointListInterpretPS(FILE *ps);
extern void PSFontInterpretPS(FILE *ps,struct charprocs *cp);

extern int SFFindChar(SplineFont *sf, int unienc, char *name );

extern char *getFontForgeDir(char *buffer);
extern void DoAutoSaves(void);
extern int DoAutoRecovery(void);
extern SplineFont *SFRecoverFile(char *autosavename);
extern void SFAutoSave(SplineFont *sf);
extern void SFClearAutoSave(SplineFont *sf);
#endif
</PRE>
</BLOCKQUOTE>
</DIV>
</BODY></HTML>
